<template>
  <div class="execution">
    <basic-container>
      <avue-form :option="tableOption" v-model="spuForm" v-loading="loading" @submit="handleSubmit">
        <template slot="spuAttrList">
          <el-tree ref="treeBase" :data="spuAttrBaseData" :props="spuAttrProps" node-key="id" default-expand-all show-checkbox @check-change="handleCheckChangeBase">
          </el-tree>
        </template>
        <template slot="spuAttrSaleTitle">
          <span style="color: grey;">最多添加两个商品属性，第一个商品属性可添加属性图片</span>
        </template>
        <template slot="spuAttrSale">
          <el-tree ref="tree" :data="spuAttrData" :props="spuAttrProps" default-expand-all draggable show-checkbox :allow-drop="allowDrop" :allow-drag="allowDrag" @check-change="handleCheckChange">
          </el-tree>
        </template>
        <template slot="skuPublishList">
          <!-- 批量设置 -->
          <div class="batch-settings" v-if="nodeLen > 0">
            <div class="batch">
              <div class="set-tips">在下方栏中选择内容进行批量填充</div>
              <el-button size="mini" plain @click="setNow" class="set">批量设置</el-button>
            </div>
            <div class="bat-set-sel">
              <el-select v-if="firstNodes.length>0" v-model="firstSkuVal" size="mini" class="bat-set-item" placeholder="请选择" style="width:120px !important">
                <el-option label="全部" value="0" />
                <el-option v-for="item in firstNodes" :key="item.id" :label="item.name" :value="item.id" />
              </el-select>
              <el-select v-if="secendNodes && secendNodes.length>0" v-model="secendSkuVal" size="mini" class="bat-set-item" placeholder="请选择" style="width:120px !important">
                <el-option label="全部" value="0" />
                <el-option v-for="item in secendNodes" :key="item.id" :label="item.name" :value="item.id" />
              </el-select>
              <!-- 库存 -->
              <el-input class="bat-set-item" size="mini" v-model.number="batchFrom.stock" :mini="0 " oninput="this.value=this.value.replace(/^\.+|[^\d.]/g,'')" placeholder="库存" style="width:120px" />
              <!-- 市场价 -->
              <el-input-number class="bat-set-item" type='number' controls-position="right" :precision="2" :step="0.1" :min="0" :max="1000000000" size="mini" v-model.number="batchFrom.marketPriceFee" placeholder="市场价" style="width:120px" />
              <!-- 销售价 -->
              <el-input-number class="bat-set-item" type='number' controls-position="right" :precision="2" :step="0.1" :min="0.01" :max="1000000000" size="mini" v-model.number="batchFrom.priceFee" placeholder="销售价" style="width:120px" />
              <!-- 商品条形码 -->
              <el-input class="bat-set-item" size="mini" v-model.number="batchFrom.modelId" oninput="this.value=this.value.replace(/^\.+|[^\d.]/g,'')" placeholder="商品条形码" style="width:190px" />
              <!-- 商品编码 -->
              <el-input class="bat-set-item" size="mini" v-model.number="batchFrom.partyCode" oninput="this.value=this.value.replace(/^\.+|[^\d.]/g,'')" placeholder="商品编码" style="width:190px" />
              <el-upload action="/admin/sys-file/upload" :headers="headers" list-type="picture-img" :show-file-list="false" :on-success="handleBatchImgUrlSuccess" :before-upload="beforeUpload" class="bat-set-item el-input imgUrl-uploader" style="background-color: #fbfdff;border: 1px dashed #c0ccda;border-radius: 6px;box-sizing: border-box;width:102px;height:102px;vertical-align: middle;">
                <img v-if="batchFrom.imgUrl" :src="batchFrom.imgUrl" class="imgUrl">
                <i v-else class="el-icon-plus imgUrl-uploader-icon"></i>
              </el-upload>
            </div>
          </div>
          <el-table :data="spuForm.skuPublishList" border size="small" style="width: 100%">
            <template v-for="(item, index) in columns">
              <el-table-column :label="item.name" :key="index">
                <template slot-scope="scope">
                  {{scope.row.attrOptionList[index].name}}
                </template>
              </el-table-column>
            </template>
            <el-table-column prop="stock" label="库存">
              <template slot-scope="scope">
                <el-input-number :min="0" v-model.number="scope.row.stock" controls-position="right" class="tab-int"></el-input-number>
              </template>
            </el-table-column>
            <el-table-column prop="marketPriceFee" label="市场价(元)">
              <template slot-scope="scope">
                <el-input-number :min="0" :max="1000000000" v-model="scope.row.marketPriceFee" controls-position="right" :precision="2" class="tab-int"></el-input-number>
              </template>
            </el-table-column>
            <el-table-column prop="priceFee" label="畅销价(元)">
              <template slot-scope="scope">
                <el-input-number :min="0.01" :max="1000000000" v-model="scope.row.priceFee" controls-position="right" :precision="2" class="tab-int"></el-input-number>
              </template>
            </el-table-column>
            <el-table-column prop="modelId" label="商品条形码">
              <template slot-scope="scope">
                <el-input :min="0" v-model.number="scope.row.modelId" oninput="this.value=this.value.replace(/^\.+|[^\d.]/g,'')" class="tab-int"></el-input>
              </template>
            </el-table-column>
            <el-table-column prop="partyCode" label="商品编码">
              <template slot-scope="scope">
                <el-input :min="0" v-model.number="scope.row.partyCode" oninput="this.value=this.value.replace(/^\.+|[^\d.]/g,'')" class="tab-int"></el-input>
              </template>
            </el-table-column>
            <!-- 摘自 https://www.cnblogs.com/steamed-twisted-roll/p/9473644.html -->
            <el-table-column prop="imgUrl" label="图片" width="120">
              <template slot-scope="scope">
                <el-upload action="/admin/sys-file/upload" :headers="headers" list-type="picture-img" :show-file-list="false" :on-success="function(rex, file){return handleSuccess(rex, file, scope.$index)}" :before-upload="beforeUpload" class="tab-int imgUrl-uploader">
                  <img v-if="scope.row.imgUrl" :src="scope.row.imgUrl" class="imgUrl">
                  <i v-else class="el-icon-plus imgUrl-uploader-icon"></i>
                </el-upload>
              </template>
            </el-table-column>
          </el-table>
          <p>总库存: {{sumStock}}</p>
        </template>
      </avue-form>
    </basic-container>
  </div>
</template>
<script>
import { publish } from '@/api/product/spu'
import { ownerTree } from '@/api/product/attr'
import { getStore } from "@/util/store"
import store from '@/store'
export default {
  name: 'spu',
  components: {},
  data() {
    return {
      loading: false,
      headers: {
        'TENANT-ID': getStore({ name: 'tenantId' }) ? getStore({ name: 'tenantId' }) : '1',
        'Authorization': 'Bearer ' + store.getters.access_token
      },
      spuAttrProps: {
        label: 'name',
        value: 'id'
      },
      spuAttrBaseData: [],
      spuAttrData: [],
      spuForm: {
        spuId: undefined,
        brandId: undefined,
        categoryId: undefined,
        shopId: undefined,
        name: undefined,
        sellingPoint: undefined,
        mainImgUrl: undefined,
        imgUrls: undefined,
        sortOrder: undefined,
        detail: undefined,
        stock: undefined,//总库存
        spuAttrList: [],
        skuPublishList: [{
          attrOptionList: [],
          stock: 0,//库存
          marketPriceFee: 0.00,//市场价
          priceFee: 0.01,//售价
          partyCode: undefined,//商品编码
          modelId: undefined,//商品条形码
          imgUrl: undefined,//图片
        }],
      },
      nodeBaseLen: 0,// 销售属性-选中的结果长度
      nodeLen: 0,// 销售属性-选中的结果长度
      columns: [],// 价格与库存-标题
      firstNodes: undefined,// 价格与库存-父属性下拉
      secendNodes: undefined,// 价格与库存-子属性下拉
      firstSkuVal: undefined, // 价格与库存-第一属性下拉选中子属性
      secendSkuVal: undefined, // 价格与库存-第二属性下拉选中子属性
      batchFrom: { // 批量更新-表单
        stock: undefined,
        marketPriceFee: undefined,
        priceFee: undefined,
        partyCode: undefined,
        modelId: undefined,
        imgUrl: undefined,
      },
    }
  },
  created() {
    this.init()
  },
  methods: {
    /**
     * 上传批量里面的图片
     */
    handleBatchImgUrlSuccess(res, file) {
      this.batchFrom.imgUrl = res.data.url;
    },
    /**
     * 上传表单里面的图片
     */
    handleSuccess(res, file, index) {
      this.spuForm.skuPublishList[index].imgUrl = res.data.url;
    },
    /**
     * 上传检验
     */
    beforeUpload(file) {
      const typeArr = ["image/png", "image/jpeg", "image/jpg"];
      const isJPG = typeArr.indexOf(file.type) !== -1;
      const isLt500K = file.size / 1024 < 500;

      if (!isJPG) {
        this.$message.error('只能上传jpg/png文件');
      }
      if (!isLt500K) {
        this.$message.error('上传图片大小不能超过 500KB!建议图片尺寸800*800');
      }
      return isJPG && isLt500K;
    },
    /**
     * 批量设置表单值
     */
    setNow() {
      if (this.firstSkuVal === undefined) return
      for (let i = 0; i < this.spuForm.skuPublishList.length; i++) {
        const m = this.spuForm.skuPublishList[i];

        // 第一个子属性
        if (this.firstSkuVal != 0 && this.firstSkuVal != m.attrOptionList[0].id) {
          continue
        }
        // 第二个子属性
        if (this.secendSkuVal && this.secendSkuVal != 0 && this.secendSkuVal != m.attrOptionList[1].id) {
          continue
        }
        m.stock = this.batchFrom.stock
        m.marketPriceFee = this.batchFrom.marketPriceFee
        m.priceFee = this.batchFrom.priceFee
        m.partyCode = this.batchFrom.partyCode
        m.modelId = this.batchFrom.modelId
        m.imgUrl = this.batchFrom.imgUrl
      }
    },
    handleCheckChangeBase(data, checked, indeterminate) {
      // 如果是父节点 勾选->默认选择第一个
      if (data.children && data.children.length > 1) {
        return
      }
      // 叶子节点
      if (checked) {
        this.$refs.treeBase.setChecked(data.parentId, false, true)
        let checkedKeys = this.$refs.treeBase.getCheckedKeys(true)
        this.$refs.treeBase.setCheckedKeys([...checkedKeys, data.id])
      }
      let nodes = this.$refs.treeBase.getCheckedNodes(true)
      this.spuForm.spuAttrList = nodes
    },
    /**
     * 选中属性 更改表单结构
     * @param data 节点
     * @param checked 节点本身是否被选中
     * @param indeterminate 节点的子树中是否有被选中的节点
     */
    handleCheckChange(data, checked, indeterminate) {
      // 获取选中值(1. 是否只是叶子节点，默认值为 false 2. 是否包含半选节点，默认值为 false)
      let nodes = this.$refs.tree.getCheckedNodes(false, true)
      if (this.nodeLen === nodes.length) {
        return
      }
      this.nodeLen = nodes.length
      // 处理table逻辑
      let parentGroup = {}
      let childrenGroup = {}
      for (let i = 0; i < nodes.length; i++) {
        const n = nodes[i];
        if (n.children) {
          parentGroup[n.id] = n
        } else {
          if (childrenGroup[n.parentId]) {
            childrenGroup[n.parentId].push(n)
          } else {
            childrenGroup[n.parentId] = []
            childrenGroup[n.parentId].push(n)
          }
        }
      }
      this.columns = Object.values(parentGroup)
      this.firstNodes = Object.values(childrenGroup)[0]
      this.secendNodes = Object.values(childrenGroup)[1]
      // 笛卡尔积
      let skuPublishList = this.calcDescartes(Object.values(childrenGroup))
      this.spuForm.skuPublishList = skuPublishList
    },
    /**
     * 笛卡尔积算法
     */
    calcDescartes(array) {
      if (array.length < 2) {
        if (array[0]) {
          let res = [];
          array[0].forEach(cv => {
            res.push(this.baseOption([cv]));
          })
          return res;
        }
        return []
      };

      return array.reduce((total, currentValue) => {
        let res = [];

        total.forEach(t => {
          currentValue.forEach(cv => {
            if (t instanceof Array)
              res.push(this.baseOption([...t, cv]));
            else
              res.push(this.baseOption([t, cv]));
          })
        })
        return res;
      })
    },
    baseOption(attrOptionList) {
      return {
        attrOptionList: attrOptionList,
        stock: 0,
        marketPriceFee: 0.00,
        priceFee: 0.00,
        modelId: undefined,
        partyCode: undefined,
      }
    },
    /**
     * 控制属性只能在同级拖拽
     */
    allowDrop(draggingNode, dropNode, type) {
      if (type !== 'prev' && type !== 'next') {
        return false;
      }
      if (!draggingNode.isLeaf) {
        return false;
      }
      if (draggingNode.parent.id !== dropNode.parent.id) {
        return false;
      }
      return true;
    },
    /**
     * 控制属性只能在同级拖拽
     */
    allowDrag(draggingNode) {
      if (!draggingNode.isLeaf) {
        return false;
      }
      return true;
    },
    /**
     * 加载属性
     */
    init() {
      this.loading = true
      ownerTree().then(res => {
        this.loading = false
        for (let i = 0; i < res.data.data.SALE.length; i++) {
          const element = res.data.data.SALE[i];
          if (element.children) {
            element.children.map(x => {
              if (x.factId) x.id = x.factId
            })
          }
        }
        for (let i = 0; i < res.data.data.BASE.length; i++) {
          const element = res.data.data.BASE[i];
          if (element.children) {
            element.children.map(x => {
              if (x.factId) x.id = x.factId
            })
          }
        }
        this.spuAttrData = res.data.data.SALE;
        this.spuAttrBaseData = res.data.data.BASE;
      })
    },
    /**
     * 提交表单
     */
    handleSubmit() {
      this.spuForm.stock = this.sumStock
      console.log(this.spuForm)
      publish(this.spuForm).then(res => {
        this.$message({
          message: "添加成功",
          type: 'success',
          duration: 1000,
          onClose: () => {
            this.$router.$avueRouter.closeTag()
            this.$router.push({ path: '/mall/product/spu/index', query: {} })
          }
        })
      })
    },
  },
  computed: {
    tableOption() {
      return {
        group: [{
          icon: 'el-icon-info',
          label: '商品基本信息',
          prop: 'info',
          column: [
            {
              label: "平台分类",
              prop: "categoryId",
              type: 'cascader',
              props: {
                label: 'name',
                value: 'id'
              },
              dicUrl: `/admin/product/category/tree?name=`,
              emitPath: false,// 只返回该节点的值
              search: true,
              span: 24
            },
            {
              label: "所属品牌",
              prop: "brandId",
              type: "select",
              props: {
                label: 'name',
                value: 'brandId'
              },
              formatter: (val, value, label) => {
                return `${label}(${value})`
              },
              dicUrl: `/admin/product/brand/list`,
              search: true,
              span: 24
            },
            {
              label: "所属店铺",
              prop: "shopId",
              type: "select",
              props: {
                label: 'shopName',
                value: 'shopId'
              },
              formatter: (val, value, label) => {
                return `${label}(${value})`
              },
              dicUrl: `/admin/product/shopDetail/list`,
              search: true,
              span: 24
            },
            {
              label: "商品标题",
              prop: "name",
              type: "input",
              placeholder: "请输入 商品标题,组成：商品描述+属性",
              search: true,
              span: 24
            },
            {
              label: "商品卖点",
              prop: "sellingPoint",
              type: "textarea",
              span: 24
            },
            {
              label: "商品主图",
              prop: "mainImgUrl",
              type: "upload",
              listType: 'picture-img',
              dataType: 'string',
              tip: '只能上传jpg/png文件,且不超过500kb',
              action: '/admin/sys-file/upload',
              propsHttp: {
                res: 'data'
              },
            },
            {
              label: "商品轮播图",
              prop: "imgUrls",
              type: "upload",
              listType: 'picture-card',
              dataType: 'string',
              tip: '只能上传jpg/png文件,且不超过500kb,建议图片尺寸800*800,最多9张',
              action: '/admin/sys-file/upload',
              propsHttp: {
                res: 'data'
              },
              span: 24,
            },
            {
              label: "排序",
              prop: "sortOrder",
              type: "input",
              span: 24
            }
          ]
        }, {
          icon: 'el-icon-info',
          label: '商品规格',
          column: [
            {
              label: "规格属性",
              prop: "spuAttrList",
              slot: true,
              span: 24,
            }
          ]
        }, {
          icon: 'el-icon-info',
          label: '商品销售属性与库存',
          column: [
            {
              label: "销售属性",
              prop: "spuAttrSaleTitle",
              slot: true,
              span: 24,
            }, {
              label: '销售属性',
              prop: 'spuAttrSale',
              slot: true,
              span: 24,
            }, {
              label: '价格与库存',
              prop: 'skuPublishList',
              slot: true,
              span: 24,
            }
          ]
        }, {
          icon: 'el-icon-info',
          label: '详情',
          column: [
            {
              label: "商品详情",
              prop: "detail",
              component: "AvueUeditor",
              options: {
                action: "/admin/sys-file/upload",
                props: {
                  res: "data",
                  url: "url",
                },
              },
              span: 24
            }
          ]
        }]
      }
    },
    option() {
      return {
        addBtn: false,
        addRowBtn: false,
        cellBtn: true,
        menu: false,
        size: "mini",
        column: [{
          label: '库存',
          prop: 'stock',
          value: 0,
          cell: true,
        }, {
          label: '市场价',
          prop: 'marketPriceFee',
          value: 0.00,
          cell: true,
        }, {
          label: '畅销价',
          prop: 'priceFee',
          value: 0.00,
          cell: true,
        }, {
          label: '商品条形码',
          prop: 'modelId',
          cell: true,
        }, {
          label: '商品编码',
          prop: 'partyCode',
          cell: true,
        }]
      }
    },
    sumStock() {
      let sum = 0
      for (let i = 0; i < this.spuForm.skuPublishList.length; i++) {
        const e = this.spuForm.skuPublishList[i];
        sum += e.stock
      }
      return sum
    },
  }
}
</script> 

<style scoped>
.batch-settings {
  margin-bottom: 15px;
}
.batch-settings .batch {
  display: flex;
  align-items: center;
  justify-content: start;
  margin-bottom: 10px;
  gap: 10px;
}
.batch-settings .batch .set-now {
  font-size: 14px;
  line-height: 1em;
  padding: 6px 10px;
  color: #02a1e9;
  border: 1px solid #02a1e9;
  cursor: pointer;
}
.batch-settings .batch .set.el-button {
  border-color: #02a1e9;
  color: #02a1e9;
}
.batch-settings .batch .set.el-button:active {
  background: #ecf5ff;
}
.batch-settings .batch .set-tips {
  font-size: 13px;
  color: #999;
  margin-left: 15px;
}

.batch-settings .bat-set-item {
  margin-right: 10px;
}

::v-deep .el-table th {
  background-color: #ccc;
}
.imgUrl-uploader .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}
.imgUrl-uploader .el-upload:hover {
  border-color: #409eff;
}
.imgUrl-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 100px;
  height: 100px;
  line-height: 100px;
  text-align: center;
}
.imgUrl {
  width: 100px;
  height: 100px;
  display: block;
}
</style>

